import json
from datetime import date, datetime, time
from decimal import Decimal
from enum import Enum
from uuid import UUID

import numpy as np


class CustomEncoder(json.JSONEncoder):
    """
    自定义JSON编码器，处理Python中各种特殊数据类型
    """

    def default(self, obj):
        # 处理Decimal类型
        if isinstance(obj, Decimal):
            # 将Decimal转换为float或字符串
            return float(obj)  # 或者使用str(obj)保持精度

        # 处理日期时间类型
        elif isinstance(obj, datetime):
            # 将datetime转换为ISO格式字符串
            return obj.isoformat()
        elif isinstance(obj, date):
            # 将date转换为ISO格式字符串
            return obj.isoformat()
        elif isinstance(obj, time):
            # 将time转换为ISO格式字符串
            return obj.isoformat()

        # 处理bytes类型
        elif isinstance(obj, bytes):
            # 处理bytes类型，尝试解码为UTF-8
            try:
                return obj.decode("utf-8")
            except UnicodeDecodeError:
                # 如果无法解码为UTF-8，返回Base64编码
                import base64

                return base64.b64encode(obj).decode("ascii")

        # 处理UUID类型
        elif isinstance(obj, UUID):
            return str(obj)

        # 处理枚举类型
        elif isinstance(obj, Enum):
            return obj.value

        # 处理NumPy数据类型
        elif isinstance(obj, (np.integer, np.floating)):
            return obj.item()
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        elif isinstance(obj, np.bool_):
            return bool(obj)

        # 处理集合类型
        elif isinstance(obj, (set, frozenset)):
            return list(obj)

        # 处理自定义对象（有__dict__属性）
        elif hasattr(obj, "__dict__"):
            # 可以添加自定义序列化逻辑
            result = dict(obj.__dict__)
            # 可选：移除私有属性（以下划线开头的属性）
            result = {k: v for k, v in result.items() if not k.startswith("_")}
            return result

        # 处理可迭代对象但不是字符串的情况
        elif hasattr(obj, "__iter__") and not isinstance(obj, str):
            try:
                return list(obj)
            except TypeError:
                pass

        # 如果无法处理，调用父类方法（会抛出TypeError）
        return super(CustomEncoder, self).default(obj)
